﻿using AngleSharp.Io;
using RndMaterialDisposalService.Attrbutes;
using RndMaterialDisposalService.Helper;
using RndMaterialDisposalService.Models;
using RndMaterialDisposalService.Models.Entitys;
using RndMaterialDisposalService.Models.RequestModel;
using RndMaterialDisposalService.Models.ResponseModel;
using RndMaterialDisposalService.Services.Interface;
using Ganss.Excel;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.EntityFrameworkCore;
using NPOI.SS.Formula.Functions;
using System.Text.Json;

namespace RndMaterialDisposalService.Controllers
{
    /// <summary>
    /// 资产转移电子流
    /// </summary>
    [Route("api/[controller]")]
    [ApiController]
    public class CapitalTransferElectronFlowController : ControllerBase
    {
        private readonly string ProcessFullName = "AssetsManagement\\AssetTransfer";

        private readonly string UpdateFormDataUrl = "/api/WorkflowData/UpdateApplicationData";
        private readonly string SaveFormDataUrl = "/api/WorkflowData/ApplicationData";
        private readonly string StartProcessUrl = "/api/WorkflowInstance";
        private readonly string ProcessFolioUrl = "/api/WorkflowData/ApplicationNumber";
        private readonly string ApprovalHistoryUrl = "/api/WorkflowData/ApplicationApproveData";
        private readonly string WorkflowTaskUrl = "/api/WorkflowTask";
        private readonly string WorkflowItemUrl = "/api/EDPPlatform/TaskItem2";
        private readonly string DoneItemUrl = "/api/EDPPlatform/CreateHaveDoneItem";
        private readonly string ProcessRedirectUrl = "/api/WorkflowTaskRedirect";


        private IConfiguration configuration;
        private IDataDictionaryService dictService;
        private ILogger<CapitalTransferElectronFlowController> logger;
        private ICapitalTransferReportFormService capitalTransferReportFormService;
        private readonly IWebHostEnvironment webHostEnvironment;


        /// <summary>
        /// 
        /// </summary>
        /// <param name="_configuration"></param>
        /// <param name="_dictService"></param>
        /// <param name="_webHostEnvironment"></param>
        /// <param name="_logger"></param>
        /// <param name="_capitalTransferReportFormService"></param>
        public CapitalTransferElectronFlowController(
            IConfiguration _configuration,
            IDataDictionaryService _dictService,
            IWebHostEnvironment _webHostEnvironment,
            ILogger<CapitalTransferElectronFlowController> _logger,
            ICapitalTransferReportFormService _capitalTransferReportFormService)
        {
            logger = _logger;
            dictService = _dictService;
            configuration = _configuration;
            webHostEnvironment = _webHostEnvironment;
            capitalTransferReportFormService = _capitalTransferReportFormService;
        }

        /// <summary>
        /// 发起流程实例
        /// </summary>
        /// <param name="reqModel"></param>
        /// <returns></returns>
        [HttpPost("StartWorkflow")]
        public async Task<IActionResult> StartWorkflow([FromBody] ApplicationDataReq reqModel)
        {
            var WorkflowHost = configuration.GetSection("WorkflowHost").Value;
            var CommonServiceHost = configuration.GetSection("CommonServiceHost").Value;

            var saveApplicationDataUrl = $"{CommonServiceHost}{SaveFormDataUrl}";
            var updateApplicationDataUrl = $"{CommonServiceHost}{UpdateFormDataUrl}";
            var startUrl = $"{WorkflowHost}{StartProcessUrl}";

            var updateProcInstId = false;
            if (reqModel.ApplicationData.Id > 0)
            {
                //1.1、更新表单数据
                reqModel.ApplicationData.Id = await HttpHelper.PostAsync<int>(updateApplicationDataUrl, JsonSerializer.Serialize(reqModel.ApplicationData));
            }
            else
            {
                //1.2、保存表单数据
                reqModel.ApplicationData.Id = await HttpHelper.PostAsync<int>(saveApplicationDataUrl, JsonSerializer.Serialize(reqModel.ApplicationData));
                updateProcInstId = true;
            }


            //2、发起流程
            if (string.IsNullOrEmpty(reqModel.ApplicationData.ProcInstId))
            {
                reqModel.DataField.Add(new DataFieldModel { Key = "FormId", Value = reqModel.ApplicationData.Id });
                var startWorkflowModel = new WorkflowInstanceModel();
                startWorkflowModel.WorkflowName = reqModel.ProcessFullName;
                startWorkflowModel.OriginatorID = reqModel.ApplicationData.ApplicationId;
                startWorkflowModel.Folio = $"{reqModel.ApplicationData.WorkflowName}-{reqModel.ApplicationData.ApplicationNumber}-{reqModel.ApplicationData.ApplicantName}";
                startWorkflowModel.DataFields = reqModel.DataField;
                reqModel.ApplicationData.ProcInstId = await HttpHelper.PostAsync<string>(startUrl, JsonSerializer.Serialize(startWorkflowModel));
            }

            if (updateProcInstId)
            {
                //3、更新表单流程实例ID
                await HttpHelper.PostAsync(updateApplicationDataUrl, JsonSerializer.Serialize(reqModel.ApplicationData));
            }


            return Ok(new { formId = reqModel.ApplicationData.Id, procInstId = reqModel.ApplicationData.ProcInstId });
        }

        /// <summary>
        /// 获取表单数据
        /// </summary>
        /// <param name="procInstID"></param>
        /// <returns></returns>
        [HttpGet("GetFormData")]
        public async Task<IActionResult> GetFormData(string? procInstID)
        {
            var CommonServiceHost = configuration.GetSection("CommonServiceHost").Value;
            var result = new FormInfoResp();
            if (!string.IsNullOrEmpty(procInstID))
            {
                var url = $"{CommonServiceHost}{SaveFormDataUrl}?procInstID={procInstID}";
                result = await HttpHelper.GetAsync<FormInfoResp>(url);
                result.ViewsStatus = "Approval";
                return Ok(result);
            }

            var formDataModel = new CapitalTransferElectronFlowReq();
            var url2 = $"{CommonServiceHost}{ProcessFolioUrl}?workflowCode={ProcessFullName}";
            var appNumber = await HttpHelper.GetAsync<string>(url2);
            result.ApplicationNumber = appNumber;
            result.ViewsStatus = "Start";
            result.FormData = JsonSerializer.Serialize(formDataModel, new JsonSerializerOptions()
            {
                PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
            });
            return Ok(result);
        }

        /// <summary>
        /// 获取审批历史
        /// </summary>
        /// <param name="workflowName"></param>
        /// <param name="applicationNumber"></param>
        /// <returns></returns>
        [HttpGet("ApprovalHistory")]
        public async Task<IActionResult> ApprovalHistory(string workflowName, string applicationNumber)
        {
            var CommonServiceHost = configuration.GetSection("CommonServiceHost").Value;
            var url = $"{CommonServiceHost}{ApprovalHistoryUrl}?workflowName={workflowName}&applicationNumber={applicationNumber}";
            var response = await HttpHelper.GetAsync<List<ApprovalHistoryResp>>(url);
            return Ok(response);
        }

        /// <summary>
        /// 新增审批历史
        /// </summary>
        /// <param name="approvalHistory"></param>
        /// <returns></returns>
        [HttpPost("AddApprovalHistory")]
        public async Task<IActionResult> ApprovalHistory(ApprovalHistoryResp approvalHistory)
        {
            try
            {
                approvalHistory.FormData = "";
                var CommonServiceHost = configuration.GetSection("CommonServiceHost").Value;
                var parms = JsonSerializer.Serialize(approvalHistory);
                var url = $"{CommonServiceHost}{ApprovalHistoryUrl}";
                var response = await HttpHelper.PostAsync($"{url}", parms);
                return Ok(response);
            }
            catch (Exception ex)
            {
                logger.LogInformation($"新增审批历史,数据包：{Newtonsoft.Json.JsonConvert.SerializeObject(approvalHistory)},时间：{DateTime.Now},异常原因：{ex.ToString()}");
                throw;
            }
        }

        /// <summary>
        /// 审批流程
        /// </summary>
        /// <param name="approvalTaskReq"></param>
        /// <returns></returns>
        [HttpPost("ApprovalTask")]
        public async Task<IActionResult> ApprovalTask(ApprovalTaskReq approvalTaskReq)
        {

            try
            {
                var WorkflowHost = configuration.GetSection("WorkflowHost").Value;
                var url = $"{WorkflowHost}{WorkflowTaskUrl}";
                var response = await HttpHelper.PostAsync(url, JsonSerializer.Serialize(approvalTaskReq));
                return Ok(response);
            }
            catch (Exception ex)
            {
                logger.LogInformation($"审批流程,数据包：{Newtonsoft.Json.JsonConvert.SerializeObject(approvalTaskReq)},时间：{DateTime.Now},异常原因：{ex.ToString()}");
                throw;
            }
        }

        /// <summary>
        /// 获取代办
        /// </summary>
        /// <param name="userId"></param>
        /// <param name="procInstID"></param>
        /// <param name="functionId"></param>
        /// <returns></returns>
        [HttpGet("GetWorkItem")]
        [PageList]
        public async Task<IActionResult> WorkItemTask(string userId, string procInstID, string functionId)
        {
            var CommonServiceHost = configuration.GetSection("CommonServiceHost").Value;
            var url = $"{CommonServiceHost}{WorkflowItemUrl}?userId={userId}&functionId={functionId}&procInstID={procInstID}";
            try
            {
                var response = await HttpHelper.GetAsync<WorkItemResp>(url);
                return Ok(ApiResponse<WorkItemResp>.Success(response));
            }
            catch (Exception)
            {
                var response = ApiResponse<string>.Fail("未获取到代办数据");
                return Ok(response);
            }
        }

        /// <summary>
        /// 新增已办数据
        /// </summary>
        /// <param name="workDone"></param>
        /// <param name="applicationNumber"></param>
        /// <returns></returns>
        [HttpPost("AddWorkDone/{applicationNumber}")]
        public async Task<IActionResult> AddWorkDone(WorkDoneReq workDone, string applicationNumber)
        {
            try
            {
                var CommonServiceHost = configuration.GetSection("CommonServiceHost").Value;
                var url = $"{CommonServiceHost}{DoneItemUrl}";
                var response = await HttpHelper.PostAsync(url, JsonSerializer.Serialize(workDone));
                return Ok(response);
            }
            catch (Exception ex)
            {
                logger.LogInformation($"新增已办数据,数据包：{Newtonsoft.Json.JsonConvert.SerializeObject(workDone)},单号：{applicationNumber},时间：{DateTime.Now},异常原因：{ex.ToString()}");
                throw;
            }
        }

        /// <summary>
        /// 流程转办
        /// </summary>
        /// <param name="serialNumber"></param>
        /// <param name="originalUser"></param>
        /// <param name="redirectToUser"></param>
        /// <returns></returns>
        [HttpPost("RedirectTask")]
        public async Task<IActionResult> RedirectTask(string serialNumber, string originalUser, string redirectToUser)
        {
            var WorkflowHost = configuration.GetSection("WorkflowHost").Value;
            var url = $"{WorkflowHost}{ProcessRedirectUrl}";
            var data = new
            {
                SerialNumber = serialNumber,
                OriginalUser = originalUser,
                RedirectToUser = redirectToUser
            };
            var response = await HttpHelper.PostAsync(url, JsonSerializer.Serialize(data));
            // TODO ...1、写审批日志   2、更新流程状态
            return Ok(response);
        }

        /// <summary>
        /// 更新表单数据
        /// </summary>
        /// <param name="reqModel"></param>
        /// <returns></returns>
        [HttpPost("PostUpdateFormData")]
        public async Task<IActionResult> UpdateFormData([FromBody] ApplicationData reqModel)
        {
            try
            {
                var CommonServiceHost = configuration.GetSection("CommonServiceHost").Value;
                var url = $"{CommonServiceHost}{UpdateFormDataUrl}";
                var result = await HttpHelper.PostAsync(url, JsonSerializer.Serialize(reqModel));
                return Ok(result);
            }
            catch (Exception ex)
            {
                logger.LogInformation($"更新表单数据,数据包：{Newtonsoft.Json.JsonConvert.SerializeObject(reqModel)},时间：{DateTime.Now},异常原因：{ex.ToString()}");
                throw;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="formReq"></param>
        /// <returns></returns>
        [HttpPost("UpdateFormData")]
        public async Task<IActionResult> UpdateFormData2(UpdateFormReq formReq)
        {
            var CommonServiceHost = configuration.GetSection("CommonServiceHost").Value;
            var url = $"{CommonServiceHost}{SaveFormDataUrl}?procInstID={formReq.ProcInstID}";
            var formData = await HttpHelper.GetAsync<ApplicationData>(url);
            if (formReq.CurrentHandler != "")
            {
                formData.CurrentHandler = formReq.CurrentHandler ?? "";
            }
            if (!string.IsNullOrEmpty(formReq.CurrentStatus))
            {
                formData.CurrentStatus = formReq.CurrentStatus;
            }
            if (!string.IsNullOrEmpty(formReq.JsonData))
            {
                formData.FormData = formReq.JsonData;
            }
            if (!string.IsNullOrEmpty(formReq.MailBody))
            {
                formData.MailBody = formReq.MailBody;
            }
            var result = await HttpHelper.PostAsync($"{CommonServiceHost}{UpdateFormDataUrl}", JsonSerializer.Serialize(formData));
            return Ok(result);
        }

        /// <summary>
        /// 文件上传
        /// </summary>
        /// <param name="file"></param>
        /// <param name="folio"></param>
        /// <returns></returns>
        /// <exception cref="Exception"></exception>
        [HttpPost("UploadFile")]
        [DisableRequestSizeLimit]
        public async Task<IActionResult> UploadFiles(IFormFile file, string folio)
        {
            if (file.Length > 1024 * 1024 * 100)
            {
                throw new Exception("上传文件不能超过100M");
            }
            var Paths = configuration.GetValue<string>("FileUploadPath");
            //string Paths = Path.GetFullPath(".");
            var filePath = $"{Paths}\\{folio}\\";
            if (!System.IO.Directory.Exists(filePath))
            {
                Directory.CreateDirectory(filePath);
            }
            var fileId = Guid.NewGuid().ToString("N");
            var fileExtension = Path.GetExtension(file.FileName);
            var newfileName = $"{fileId}{fileExtension}";
            var saveName = filePath + newfileName;
            using (FileStream fs = System.IO.File.Create(saveName))
            {
                await file.CopyToAsync(fs);
                fs.Flush();
            }
            var result = new
            {
                FileId = fileId,
                FileName = newfileName,
                FileSize = file.Length,
                OriginalName = file.FileName,
                FilePath = $"{folio}\\{newfileName}"
            };
            return Ok(result);
        }

        /// <summary>
        /// 文件下载
        /// </summary>
        /// <param name="relativePath"></param>
        /// <param name="fileName"></param>
        /// <param name="clearFile"></param>
        /// <returns></returns>
        [HttpGet("DownloadFile")]
        [PageList]
        public async Task<IActionResult> DownloadFile(string relativePath, string fileName, bool clearFile = false)
        {
            var fileDir = configuration.GetValue<string>("FileUploadPath");
            var fileFullPath = $"{fileDir}\\{relativePath}";
            if (!System.IO.File.Exists(fileFullPath))
            {
                throw new Exception($"{relativePath}文件不存在");
            }
            var stream = await System.IO.File.ReadAllBytesAsync(fileFullPath);
            if (clearFile)
            {
                System.IO.File.Delete(fileFullPath);
            }
            return File(stream, "application/octet-stream", fileName);
        }

        /// <summary>
        /// 保存报表数据
        /// </summary>
        /// <param name="formData"></param>
        /// <returns></returns>
        [HttpPost("SaveReportData")]
        public async Task<IActionResult> SaveReportData(CapitalTransferElectronFlowReq formData)
        {
            string _ProcInstId = formData.FormHeader.ProcInstId ?? "0";
            try
            {
                var result = await capitalTransferReportFormService.AddCapitalRepairBusinessData(formData);
                logger.LogInformation($"新增报表数据（资产转移电子流）,流程实例号：{_ProcInstId},数量：{result},时间：{DateTime.Now}");
                return Ok(result);
            }
            catch (Exception ex)
            {
                logger.LogInformation($"新增报表数据（资产转移电子流）,流程实例号：{_ProcInstId},异常原因：{ex.ToString()},时间：{DateTime.Now}");
                throw;
            }
        }

        /// <summary>
        /// 返回资产转移电子流报表主数据
        /// </summary>
        /// <param name="inputCondition"></param>
        /// <returns></returns>
        [HttpPost("CapitalTransferReportFormData")]
        [PageList]
        public IActionResult GetCapitalTransferReportFormData(CapitalTransferReportConditionModel inputCondition)
        {
            var data = capitalTransferReportFormService.GetCapitalTransferReportFormPageList(inputCondition);
            var result = ApiResponsePageList<CapitalTransferReportFormModel>.CreatePageListByResult(data.list, inputCondition.pageIndex, inputCondition.pageSize, data.count);
            return Ok(result);
        }

        /// <summary>
        /// 导出报表文件
        /// </summary>
        /// <param name="inputCondition"></param>
        /// <returns></returns>
        [HttpPost("CapitalTransferReportExport")]
        [PageList]
        public async Task<IActionResult> CapitalTransferReportExport(CapitalTransferReportConditionModel inputCondition)
        {
            inputCondition.pageIndex = 1;
            inputCondition.pageSize = 65535;
            var data = capitalTransferReportFormService.GetCapitalTransferReportFormPageList(inputCondition);
            var fileDir = configuration.GetValue<string>("FileUploadPath");
            if (!System.IO.Directory.Exists($"{fileDir}\\Report"))
            {
                Directory.CreateDirectory($"{fileDir}\\Report");
            }
            var filePath = $"Report\\资产转移电子流报表{Guid.NewGuid().ToString("N")}.xlsx";
            await new ExcelMapper().SaveAsync($"{fileDir}\\{filePath}", data.list);
            return Ok(filePath);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="formDataModify"></param>
        /// <returns></returns>
        [HttpPost("AddFormDataModifyLog")]
        [PageList]
        public async Task<int> AddFormDataModifyLog(FormDataModifyLogDto formDataModify)
        {
            formDataModify.SysId = Guid.NewGuid();
            formDataModify.MidifityTime = DateTime.Now;
            return await capitalTransferReportFormService.AddFormDataModifyLog(formDataModify);
        }
    }
}
